package com.example.demo.sql.condition;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;

import java.util.ArrayList;
import java.util.List;

public class CompositeCondition {
    private List<Condition> conditions;
    private List<String> operators; // "AND" or "OR"
    private List<Integer> parentheses; // Indices of where to add parentheses

    public CompositeCondition(List<Condition> conditions, List<String> operators, List<Integer> parentheses) {
        this.conditions = conditions;
        this.operators = operators;
        this.parentheses = parentheses;
    }

    public Expression toExpression() {
        if (conditions.size() == 1) {
            return conditions.get(0).toExpression();
        }

        List<Expression> expressions = new ArrayList<>();
        for (Condition condition : conditions) {
            expressions.add(condition.toExpression());
        }

        // Apply parentheses
        for (int i = parentheses.size() - 1; i >= 0; i--) {
            int index = parentheses.get(i);
            if (index < 0 || index >= conditions.size()) {
                throw new IllegalArgumentException("Invalid parentheses index: " + index);
            }
            Expression left = expressions.get(index);
            if (index + 1 < conditions.size()) {
                Expression right = expressions.get(index + 1);
                expressions.set(index, new Parenthesis(new AndExpression(left, right)));
                expressions.remove(index + 1);
            }
        }

        // Combine expressions with operators
        Expression result = null;
        for (int i = 0; i < expressions.size(); i++) {
            Expression currentExpr = expressions.get(i);

            if (i == 0) {
                result = currentExpr;
            } else {
                String operator = operators.get(i - 1);
                if ("AND".equals(operator)) {
                    result = new AndExpression(result, currentExpr);
                } else if ("OR".equals(operator)) {
                    result = new OrExpression(result, currentExpr);
                } else {
                    throw new IllegalArgumentException("Unsupported operator: " + operator);
                }
            }
        }

        return result;
    }
}

